package org.gavin.core.service.safety.impl;

import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.gavin.core.attribute.YmlSafetyAttribute;
import org.gavin.core.constant.CommonConst;
import org.gavin.core.enums.CommonStatus;
import org.gavin.core.enums.SafetyType;
import org.gavin.core.exception.ConfigException;
import org.gavin.core.exception.ParamException;
import org.gavin.core.service.safety.SafetyAbstract;
import org.gavin.core.utils.GMSM4Utils;

import java.util.Map;

/**
 * SafetyAttribute
 *
 * @author grl
 * @date 2024/1/4
 */
@Slf4j
public class YmlSafety implements SafetyAbstract {

    private final YmlSafetyAttribute ymlSafetyAttribute;

    private final HttpServletRequest request;

    public YmlSafety(YmlSafetyAttribute ymlSafety, HttpServletRequest request) {
        this.ymlSafetyAttribute = ymlSafety;
        this.request = request;
    }

    @Override
    public SafetyType TYPE() {
        return SafetyType.SM4;
    }

    @Override
    public String getEncrypt(String data) {
        String appId = request.getHeader(CommonConst.SAFETY_KEY);
        String encSecret = getMultipleConfig(appId, CommonStatus.CONFIG_ERROR).getEncSecret();
        if (StringUtils.isNotBlank(encSecret)) {
            return GMSM4Utils.encryptEcb(data, encSecret);
        } else {
            log.error("加密接口没有获取到请求对应的APPID 或者 appId 不在白名单 {}", appId);
            throw ParamException.le(CommonStatus.ACCESS_DENIED);
        }
    }

    @Override
    public String getDecrypt(String data) {
        String appId = request.getHeader(CommonConst.SAFETY_KEY);
        if (StringUtils.isBlank(appId)) {
            throw ParamException.le(CommonStatus.LACK_HEADER_PARAM_ERROR, "YmlSafety", CommonConst.SAFETY_KEY);
        }
        String decSecret = getMultipleConfig(appId, CommonStatus.ACCESS_DENIED).getDecSecret();
        return GMSM4Utils.decryptEcb(data, decSecret);
    }

    private YmlSafetyAttribute.Multiple getMultipleConfig(String appId, CommonStatus status) {
        Map<String, YmlSafetyAttribute.Multiple> multipleMap = ymlSafetyAttribute.getMultiple();
        if (multipleMap == null || !multipleMap.containsKey(appId)) {
            throw ConfigException.le(status, "YmlSafety", appId);
        }
        return multipleMap.get(appId);
    }
}
